<?php

class menuHelper {

    // Associative array of list items
    public $items = array();
    // Associative array of attributes for list
    public $attrs = array();
    // Current active route
    public $current;

    public static function getMenu() {
        $menu = array
            (
            array('title' => 'Эхлэл', 'route' => 'homepage', 'icon' => 'icon-home', 'class' => 'start'),
            array('title' => 'Орлого/Зарлага', 'route' => '', 'fallback_route' => 'income_list', 'icon' => 'icon-usd', 'children' =>
                array(
                    array('title' => 'Зарлага жагсаалт', 'route' => 'outcome_list', 'icon' => 'icon-list'),
                    array('title' => 'Орлого жагсаалт', 'route' => 'income_list', 'icon' => 'icon-list'),
                    array('title' => 'Орлого нэмэх', 'route' => 'income_edit', 'icon' => 'icon-plus'),
                    array('title' => 'Шилжүүлэг', 'route' => 'transfer', 'icon' => 'icon-random'),
                )
            ),
            array('title' => 'Бараа', 'route' => '', 'fallback_route' => 'product_list', 'icon' => 'icon-barcode', 'children' =>
                array(
                    array('title' => 'Ангилал', 'route' => '', 'fallback_route' => 'category_list', 'icon' => 'icon-tags', 'children' =>
                        array(
                            array('title' => 'Жагсаалт', 'route' => 'category_list', 'icon' => 'icon-list'),
                            array('title' => 'Нэмэх', 'route' => 'category_add', 'icon' => 'icon-plus'),
                        )
                    ),
                    array('title' => 'Үйлдвэрлэгч', 'route' => '', 'fallback_route' => 'manufacturer_list', 'icon' => 'icon-bookmark', 'children' =>
                        array(
                            array('title' => 'Жагсаалт', 'route' => 'manufacturer_list', 'icon' => 'icon-list'),
                            array('title' => 'Нэмэх', 'route' => 'manufacturer_add', 'icon' => 'icon-plus'),
                        )
                    ),
                    array('title' => 'Бараа жагсаалт', 'route' => 'product_list', 'icon' => 'icon-list'),
                    array('title' => 'Нэмэх', 'route' => 'product_add', 'icon' => 'icon-plus'),
                ),
            ),
            array('title' => 'Үлдэгдэл', 'route' => '', 'fallback_route' => 'inventory_daily', 'icon' => 'icon-inbox', 'children' =>
                array(
                    array('title' => 'Өдрийн үлдэгдэл', 'route' => 'inventory_daily', 'icon' => 'icon-list'),
                    array('title' => 'Дэлгэрэнгүй үлдэгдэл', 'route' => 'inventory_detailed', 'icon' => 'icon-list'),
                ),
            ),
            array('title' => 'Ажилтнууд', 'route' => '', 'fallback_route' => 'user_list', 'icon' => 'icon-briefcase', 'children' =>
                array(
                    array('title' => 'Жагсаалт', 'route' => 'user_list', 'icon' => 'icon-list'),
                    array('title' => 'Нэмэх /Гоо сайханч/', 'route' => 'user_add', 'icon' => 'icon-plus'),
                    array('title' => 'Нэмэх /Зөвлөх/', 'route' => 'user_add_sales', 'icon' => 'icon-plus')
                )
            ),
            array('title' => 'Тайлан', 'route' => '', 'fallback_route' => 'report_outcome', 'icon' => 'icon-table', 'children' =>
                array(
                    array('title' => 'Зарлагын тайлан', 'route' => 'report_outcome', 'icon' => 'icon-usd'),
                )
            ),
            array('title' => 'Салбар', 'route' => '', 'fallback_route' => 'store_list', 'icon' => 'icon-map-marker', 'children' =>
                array(
                    array('title' => 'Жагсаалт', 'route' => 'store_list', 'icon' => 'icon-list'),
                    array('title' => 'Нэмэх', 'route' => 'store_add', 'icon' => 'icon-plus')
                )
            ),
            array('title' => 'Гишүүд', 'route' => '', 'fallback_route' => 'customer_list', 'icon' => 'icon-user', 'children' =>
                array(
                    array('title' => 'Жагсаалт', 'route' => 'customer_list', 'icon' => 'icon-list'),
                    array('title' => 'Нэмэх', 'route' => 'customer_add', 'icon' => 'icon-plus')
                )
            ),
            array('title' => 'Санал асуулга', 'route' => '', 'fallback_route' => 'poll_list', 'icon' => 'icon-bar-chart', 'children' =>
                array(
                    array('title' => 'Жагсаалт', 'route' => 'poll_list', 'icon' => 'icon-list'),
                    array('title' => 'Нэмэх', 'route' => 'poll_add', 'icon' => 'icon-plus')
                )
            ),
        );
        return $menu;
    }

    /**
     * Creates and returns a new menu object
     *
     * @chainable
     * @param   array   Array of list items (instead of using add() method)
     * @return  menu
     */
    public static function factory(array $items = NULL) {
        return new menuHelper($items);
    }

    /**
     * Constructor, globally sets $items array
     *
     * @param   array   Array of list items (instead of using add() method)
     * @return  void
     */
    public function __construct(array $items = NULL) {
        $this->items = $items;
    }

    /**
     * Add's a new list item to the menu
     *
     * @chainable
     * @param   string   Title of link
     * @param   string   route (address) of link
     * @param   menu     Instance of class that contain children
     * @return  menu
     */
    public function add($title, $route, menuHelper $children = NULL) {
        $this->items[] = array
            (
            'title' => $title,
            'route' => $route,
            'children' => is_object($children) ? $children->items : NULL,
        );

        return $this;
    }

    /**
     * Renders the HTML output for the menu
     *
     * @param   array   Associative array of html attributes
     * @param   array   Associative array containing the key and value of current route
     * @param   array   The parent item's array, only used internally
     * @return  string  HTML unordered list
     */
    public function render(array $attrs = NULL, $current = NULL, array $items = NULL) {
        static $i;

        $items = empty($items) ? $this->items : $items;
        $current = empty($current) ? $this->current : $current;
        $attrs = empty($attrs) ? $this->attrs : $attrs;

        $i++;

        $menu = '<ul' . ($i == 1 ? self::attributes($attrs) : ' class="sub-menu"') . '>';
        $menu .= $i == 1 ? '<li><div class="sidebar-toggler hidden-phone"></div></li>' : NULL;

        foreach ($items as $key => $item) {
            $has_children = isset($item['children']);
            $has_class = isset($item['class']);

            $class = array();

            $has_class ? $class[] = $item['class'] : NULL;

            if (!empty($current)) {
                if ($current_class = self::current($current, $item)) {
                    $class[] = $current_class;
                }
            }

            $classes = !empty($class) ? self::attributes(array('class' => implode(' ', $class))) : NULL;

            $menu .= '<li' . $classes . '>';

            if ($item['route'] == '') {
                $menu .= '<a href="javascript:;">';
            } else {
                $menu .= '<a href="' . url_for('@' . $item['route']) . '">';
            }

            if (isset($item['icon'])) {
                $menu .= '<i class="' . $item['icon'] . '"></i>';
            }

            $menu .= '<span class="title">' . $item['title'] . '</span>';
            $menu .= $has_children ? '<span class="arrow"></span>' : NULL;
            $menu .= '</a>';
            $menu .= $has_children ? $this->render(NULL, $current, $item['children']) : NULL;
            $menu .= '</li>';
        }

        $menu .= '</ul>';

        $i--;

        return $menu;
    }

    /**
     * Renders the HTML output for menu without any attributes or active item
     *
     * @return   string
     */
    public function __toString() {
        return $this->render();
    }

    /**
     * Easily set the current route, or list attributes
     *
     * @param   mixed   Value to set to
     * @return  void
     */
    public function __set($key, $value) {
        $this->attrs[$key] = $value;
    }

    /**
     * Get the current route or a list attribute
     *
     * @return   mixed   Value of key
     */
    public function __get($key) {
        if (isset($this->attrs[$key]))
            return $this->attrs[$key];
    }

    /**
     * Nicely outputs contents of $this->items for debugging info
     *
     * @return   string
     */
    public function debug() {
        return '<pre>' . print_r($this->items, TRUE) . '</pre>';
    }

    /**
     * Compiles an array of HTML attributes into an attribute string.
     *
     * @param   string|array  array of attributes
     * @return  string
     */
    protected static function attributes($attrs) {
        if (empty($attrs))
            return '';

        if (is_string($attrs))
            return ' ' . $attrs;

        $compiled = '';
        foreach ($attrs as $key => $val) {
            $compiled .= ' ' . $key . '="' . htmlspecialchars($val) . '"';
        }

        return $compiled;
    }

    /**
     * Figures out if items are parents of the active item.
     *
     * @param   array   The current route array (key, match)
     * @param   array   The array to check against
     * @return  bool
     */
    protected static function current($current, array $item) {
        if ($current === $item['route'])
            return 'active current';

        else {
            if (self::active($item, $current, 'route'))
                return 'active';
        }

        return '';
    }

    /**
     * Recursive function to check if active item is child of parent item
     *
     * @param   array   The list item
     * @param   string  The current active item
     * @param   string  Key to match current against
     * @return  bool
     */
    public static function active($array, $value, $key) {
        foreach ($array as $val) {
            if (is_array($val)) {
                if (self::active($val, $value, $key))
                    return TRUE;
            }
            else {
                if ($array[$key] === $value)
                    return TRUE;
            }
        }

        return FALSE;
    }

    public static function getPath($route, $arr) {
        $result = array();
        foreach ($arr as $val) {
            if (is_array($val)) {
                if ($val['route'] == $route) {
                    $pathurl = $val['route'] ? $val['route'] : $val['fallback_route'];
                    $result[] = array('title' => $val['title'], 'route' => $pathurl);
                } elseif (!empty($val['children']) && is_array($val['children'])) {
                    $sub_res = self::getPath($route, $val['children']);
                    if (count($sub_res) > 0) {
                        $pathurl = $val['route'] ? $val['route'] : $val['fallback_route'];
                        $result[] = array('title' => $val['title'], 'route' => $pathurl);
                        $result = array_merge($result, $sub_res);
                    }
                }
            }
        }
        return $result;
    }

}
